import xlsx, { CellObject, ExcelDataType, NumberFormat } from 'sheetjs-style';

export const argbRed = 'FFFF0000';
export const argbLightOrange = 'FFFFA07A';
export const argbGreen = 'FF228B22';
export const argbLightGreen = 'FFC1FFC1';

const ColNames = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

export function getColLabel (index: number): string {
    const len = ColNames.length
    if (index < len) return ColNames[index]
    else return ColNames[Math.floor((index + 1) / len)] + ColNames[index % len]
}

export interface SheetInfo<T = any> {
    data?: T[], 
    aoa?: T[][],
    name: string, 
    wchs: number[], 
    colInfos?: {
        begin?: number, 
        end?: number, 
        cellIndex: string, 
        t: ExcelDataType, 
        z: NumberFormat
    }[], 
    decideStyle?: (ws: xlsx.WorkSheet, info: SheetInfo<T>)=>void
}

export function toXlsxSafe(v: number): number | string {
    if (isNaN(v)) {
        return '-';
    }
    return v;
}

export async function writeXlsx(file: string, sheets: SheetInfo[]): Promise<void> {
    let newBook = xlsx.utils.book_new();
    for (const st of sheets) {
        let newSheet: xlsx.WorkSheet;
        let arr: any[];
        if (st.data != null) {
            arr = st.data;
            newSheet = xlsx.utils.json_to_sheet(st.data, { skipHeader: true });
        } else if (st.aoa != null) {
            arr = st.aoa;
            newSheet = xlsx.utils.aoa_to_sheet(st.aoa);
        } else {
            continue;
        }
        
        const cols: xlsx.ColInfo[] = [];
        for (let wch of st.wchs) {
            cols.push({ wch });
        }
        newSheet['!cols'] = cols;
        if (st.colInfos) {
            for (const colInfo of st.colInfos) {
                for (let i = colInfo.begin ?? 1, len = colInfo.end ?? arr.length; i < len; i++) {
                    const cell = newSheet[`${colInfo.cellIndex}${i + 1}`] as CellObject;
                    if (colInfo.t) cell.t = colInfo.t;
                    if (colInfo.z) cell.z = colInfo.z;
                }
            }
        }
        if (st.decideStyle) st.decideStyle(newSheet, st);
        xlsx.utils.book_append_sheet(newBook, newSheet, st.name);
    }
    xlsx.writeFile(newBook, file, { cellStyles: true });
}